package belastungstest.mobapp.fhfl.mobappbelastungstest;

import android.app.Fragment;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.SeekBar;
import android.widget.TextView;

import org.achartengine.GraphicalView;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.renderer.XYMultipleSeriesRenderer;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.EventListener;

/**
 * Created by ViceBrot^^ on 07.07.2014.
 */
public class Fragment_Setting extends Fragment  implements Transmitter.ReciveEventListener {
    private Transmitter transmitter = null;
    private Transmitter.ReciveEventListener mySqelf = null;

    //region declaration of GUI Elements
    private EditText adresse;
    private EditText port;
    private Button startsend;
    private Button stopsend;
    private CheckBox endlessloop;
    private TextView transmittedkbytes;
    private TextView otransmittedkbytes;
    private SeekBar seekbarps;
    private TextView packetsize;
    private TextView latency;
    private SeekBar seekbarms;
    private TextView packetinterval;
    private ScrollView scrollLog;
    private TextView log;
    //endregion

    private long            startRun = 0;
    private long            startTime = System.currentTimeMillis();
    private int             seconds = 20;
    private int             avgLatencyCount =  0;
    private double          avgLatency =  0;
    private double          recivedKiloBytes =  0;
    private int             orecievedKiloBytes = 0;
    private int             stringPos = 0;
    private StringBuilder   LogString = new StringBuilder();
    private boolean         isRunning = false;
    BufferedWriter          writer;
    String                  filename = "";
    private Chart           chart = null;
    GraphicalView           chartView = null;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //this.requestWindowFeature(Window.FEATURE_NO_TITLE);

        View view = inflater.inflate(R.layout.activity_my, container, false);

        mySqelf = this;

        //region assign GUI Elements
        log = (TextView) view.findViewById(R.id.Log);
        scrollLog = (ScrollView) view.findViewById(R.id.scrollLog);
        adresse = (EditText) view.findViewById(R.id.editAdresse);
        port = (EditText) view.findViewById(R.id.editPort);
        startsend = (Button) view.findViewById(R.id.startsend);
        stopsend = (Button) view.findViewById(R.id.stopsend);
        endlessloop = (CheckBox) view.findViewById(R.id.checkboxendlessloop);
        transmittedkbytes = (TextView) view.findViewById(R.id.transmittedkbytes);
        otransmittedkbytes = (TextView) view.findViewById(R.id.otransmittedkbytes);
        seekbarps = (SeekBar)  view.findViewById(R.id.seekbarpacketsize);
        packetsize = (TextView)  view.findViewById(R.id.packetsize);
        latency = (TextView)  view.findViewById(R.id.latency);
        seekbarms = (SeekBar)  view.findViewById(R.id.seekbarpacketinterval);
        packetinterval = (TextView)  view.findViewById(R.id.packetinterval);
        //endregion

        if(isRunning)
        {
            seekbarms.setEnabled(false);
            seekbarps.setEnabled(false);
            endlessloop.setEnabled(false);
            startsend.setEnabled(false);
            stopsend.setEnabled(true);
        }
        else
            stopsend.setEnabled(false);

        //region startsend.setOnClickListener
        startsend.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View view)
            {
                Date actualDate = new Date();
                filename = new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss").format(actualDate)+"_Belastungstest_Log.txt";
                startRun = System.currentTimeMillis();

                try {
                    if(endlessloop.isChecked()) {
                        seekbarms.setEnabled(false);
                        seekbarps.setEnabled(false);
                        endlessloop.setEnabled(false);
                        startsend.setEnabled(false);
                        stopsend.setEnabled(true);
                    }
                    
                    if(transmitter != null)
                    {
                        transmitter.dispose();
                        transmitter = null;
                    }

                    InetAddress nowInetAddress      = InetAddress.getByName( adresse.getText()+"" );
                    int nowInetPort                 = Integer.parseInt( port.getText()+"" );
                    int nowPacketSize               = Integer.parseInt(packetsize.getText()+""  )*1024;
                    int nowPacketIntervall          = Integer.parseInt( packetinterval.getText()+"" );
                    boolean endless                 = endlessloop.isChecked();

                    transmitter = new Transmitter
                    (
                            nowInetAddress,
                            nowInetPort,
                            nowPacketSize,
                            nowPacketIntervall,
                            endless,
                            mySqelf
                    );

                    startTime = System.currentTimeMillis();
                    seconds = 20;
                    avgLatencyCount =  0;
                    avgLatency =  0;
                    recivedKiloBytes =  0;
                    orecievedKiloBytes =  0;
                    isRunning = true;

                }catch (Exception e) {
                    Log.d("bad:", "transmitter failed");
                    e.printStackTrace();
                }
            }
        });
        //endregion

        //region stopsend.setonclicklistener
        stopsend.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View view)
            {
                seekbarms.setEnabled(true);
                seekbarps.setEnabled(true);
                endlessloop.setEnabled(true);
                startsend.setEnabled(true);
                stopsend.setEnabled(false);

                isRunning = false;

                if(transmitter != null)
                {
                    transmitter.dispose();
                    transmitter = null;
                }
            }
        });


        //endregion

        //region seekbarps.setOnChangeListener
        seekbarps.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                if (i==0)
                    i=1;
                packetsize.setText(String.valueOf(i));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {}

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {}
        });
        //endregion

        //region seekbarms.setOnChangeListener
        seekbarms.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                if (i==0)
                    i=1;
                packetinterval.setText(String.valueOf(i));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {}

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {}
        });
        //endregion

        chart = new Chart();
        chartView = chart.getView(view.getContext());
        handler.postAtFrontOfQueue(updateGUI);

        return view;
    }

    public View getChartView()
    {
        return chartView;
    }

    //region Timer for Redraw
    Handler handler = new Handler();
    private Runnable updateGUI = new Runnable() {
        @Override
        public void run()
        {
            Log.d("paint:", "do");

            //newData();
            transmittedkbytes.setText( recivedKiloBytes +"" );
            otransmittedkbytes.setText(orecievedKiloBytes +"");

            //log.append( LogString.substring(stringPos) );
            //stringPos = LogString.length();

            if( avgLatencyCount != 0) {
                chart.setAvgLatency( avgLatency / avgLatencyCount );
                latency.setText(new DecimalFormat("##").format(avgLatency / avgLatencyCount));
            }
            chart.redraw();

            handler.postDelayed(this, 500);
        }
    };
    //endregion

    @Override
    public void onReciveEvent(Transmitter.ReciveEvent e)
    {
        //LogString.append( "packetIntegrety[%]:"+e.packetIntegrety+"   lostPackets"+e.lostPackets+"   avgLatency:"+avgLatency/avgLatencyCount+"  "+e.type.name()+" latency:"+e.latency+" packetNumber:"+e.packetNumber+" packetSize:"+e.packetSize+"kb" + "\n " );
        //Log.d("recive:", "packetIntegrety[%]:" + e.packetIntegrety + "   lostPackets" + e.lostPackets + "   avgLatency:" + avgLatency / avgLatencyCount + "  " + e.type.name() + " latency:" + e.latency + " packetNumber:" + e.packetNumber + " packetSize:" + e.packetSize + "kb "); //ReciveEventTypes);

        /**
         * Im logString befinden sich alle Daten welche in das Log-File geschrieben werden.
         */

        String logString =  "packetIntegrety[%]: "+e.packetIntegrety+
                            " lostPackets: "+e.lostPackets+
                            " avgLatency: "+(int)(avgLatency/avgLatencyCount)+
                            " avgRecievedKiloBytes: " + orecievedKiloBytes +
                            " latency: "+e.latency+"kB"+
                            " packetNumber: "+e.packetNumber+
                            " packetSize: "+e.packetSize+"kB"+
                            " "+e.type.name()+ "\n" +
                            "=================================================\n";

        write(filename, logString);
        avgLatency += e.latency;
        avgLatencyCount++;

        log.setText("Nachricht empfangen.");
        recivedKiloBytes += e.packetSize/1024.;
        orecievedKiloBytes = (int)recivedKiloBytes / (int)((System.currentTimeMillis() - startRun)/1000);

        long now = System.currentTimeMillis()-startTime;

        chart.addNewBandwithPoint(now, orecievedKiloBytes  );
        chart.addNewLatencyPoint(now, e.latency);
        scrollLog.smoothScrollTo(0, log.getBottom());
    }

    public void write(String fileName, String data) {
        File root = Environment.getExternalStorageDirectory();

        //Legt den Pfad fest in welchem die Logfiles gespeichert werden
        File outDir = new File(root.getAbsolutePath()+ File.separator + "MobApp_Belastungstest");
        if (!outDir.isDirectory()) {
            outDir.mkdir();
        }
        try {
            File outputFile = new File(outDir, fileName);
            writer = new BufferedWriter(new FileWriter(outputFile, true));
            writer.write(data);
            writer.close();
        } catch (IOException e) {}
    }
}
